package sgs.skin;

import java.io.*;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

//import javax.net.ssl.SSLContext;

import com.opencsv.CSVReader;
import com.opencsv.exceptions.CsvException;
import com.opencsv.exceptions.CsvValidationException;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
//import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;


/**
 * 三国杀皮肤下载
 * @author liyas
 * @since 2023-2-27
 */
public class SkinDownload {
    private static String maxBigUrl_10zn = "https://web.sanguosha.com/10/pc/res/assets/runtime/general/maxBig/";
    private static String bigUrl_10zn = "https://web.sanguosha.com/10/pc/res/assets/runtime/general/big/static/";

    private static String bigUrl_ol = "https://web.sanguosha.com/220/mobile_h5_2/res/runtime/m/general/big/static/";
    private static String maxBigUrl_ol = "https://web.sanguosha.com/220/h5_2/res/runtime/pc/general/big/bigSkin/";

    private static Map<String,String>  skindirMap = new HashMap<>();
    private static Map<String,String>  skinsrcMap = new HashMap<>();

    public static void main(String[] args) throws Exception {
        String mapDirpath = "D:\\SyncSpace\\三国杀皮肤三版合集";
        String desDirpath = "D:\\SyncSpace\\sanguosha_skin.20230225\\skin_mob";
        String srcDirpath = "D:\\SyncSpace\\sanguosha_mob.merge";
        String codeFilepath = "D:\\SyncSpace\\sanguosha_skin.20230225\\skin_mob\\skinlist_mob.csv";
        reorganizeFiles(mapDirpath, desDirpath, srcDirpath, codeFilepath);
    }


    private void downloadSkin() throws Exception {
        // N001XX~N999XX （N=1~7）
        // download(bigUrl, "D:\\SyncSpace\\sanguosha_10zn", 1001, 9999, "big");
        // N001XX~N999XX （N=1~7）
        // download(maxBigUrl, "D:\\SyncSpace\\sanguosha_10zn\\maxBig", 1001, 9999,
        // "maxBig");

        // N1000XX~N3000XX (N=1~7)
        // download_2023(bigUrl, "D:\\SyncSpace\\sanguosha_10zn", 1000, 3000, "big");
        // N1000XX~N3000XX (N=1~7)
        // download_2023(maxBigUrl, "D:\\SyncSpace\\sanguosha_10zn\\maxBig", 1000, 3000,
        // "maxBig");
        long begin = System.currentTimeMillis();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String suffix = "." + sdf.format(new Date());

        // 下载10周年皮肤 ================================================================
        String outdir = "D:/SyncSpace/sanguosha_skin.20230225/skin_10zn";
        initSkindirMap(outdir);

//		ArrayList<String[]> codelist_10zn = download_10zn_fromCsv(bigUrl_10zn, outdir, suffix, outdir + "/skinlist_10zn.csv");
//		ArrayList<String[]> codelist_10zn_2 = downloadBycode_fromCsv(bigUrl_10zn, outdir, suffix, outdir + "/skinlist_10zn_special.csv");
//
//		codelist_10zn.addAll(codelist_10zn_2);
//		downloadMaxbig(maxBigUrl_10zn, suffix, codelist_10zn);
//
//		skindirMap.clear(); // 如果需要两边保持一致的编码，则不需要清空map
        long end1 = System.currentTimeMillis();

        // 下载OL皮肤 ===============================================================
        String outdir_ol = "D:/SyncSpace/sanguosha_skin.20230225/skin_ol";
        initSkindirMap(outdir_ol);

        ArrayList<String[]> codelist = download_ol_fromCsv(bigUrl_ol, outdir_ol, suffix, outdir_ol + "/skinlist_ol.csv");
//		ArrayList<String[]> codelist2 = downloadBycode_fromCsv(bigUrl_ol, outdir_ol, suffix, outdir_ol + "/skinlist_ol_special.csv");

//		codelist.addAll(codelist2);
        downloadMaxbig(maxBigUrl_ol, suffix, codelist);

        skindirMap.clear();
        long end2 = System.currentTimeMillis();

        System.out.println("10zn total time:" + (end1 - begin) / 1000 / 60 + "min");
        System.out.println("ol total time:" + (end2 - end1) / 1000 / 60 + "min");

    }

    /**
     * 初始化皮肤目录的映射： 势力.武将 -> 皮肤目录名
     * @param outdir
     * @throws Exception
     * @author liyas
     * @since 2023-2-27
     */
    private static void initSkindirMap(String outdir) throws Exception {
        File dirfile = new File(outdir);
        if (!dirfile.exists()) {
            throw new Exception("目录不存在：" + outdir);
        }

        for (File country : dirfile.listFiles()) {
            if (!country.isDirectory()) {
                continue;
            }
            for (String skindir : country.list()) {// 遍历势力目录下的武将皮肤文件夹
                // 例：蜀.刘备 -> 蜀/ 001.刘备
                skindirMap.computeIfAbsent(country.getName() + skindir.substring(skindir.indexOf(".")), k -> country.getName() + "/" + skindir);
            }
        }
    }

    /**
     * 初始化编码文件映射
     * @param codeFilepath
     * @author liyas
     * @since 2023-3-7
     */
    private static void iniSkinsrcMap(String codeFilepath) throws IOException, CsvException {
        ArrayList<String[]> codeList = readCsvfile(codeFilepath);
        for (String[] line : codeList) { // country,name,code
            skinsrcMap.put(line[2], line[0] + "." + line[1]); // 例：1 -> 蜀.刘备
        }
    }

    /**
     * 10周年皮肤下载
     * @param baseUrl
     * @param dir
     * @param renameSuffix
     * @param csvfilePath
     * @return
     * @author liyas
     * @since 2023-2-19
     */
    private static ArrayList<String[]> download_10zn_fromCsv(String baseUrl, String dir, String renameSuffix, String csvfilePath) throws IOException, CsvException {
        // 读取csv
        ArrayList<String[]> codeList = readCsvfile(csvfilePath);
        ArrayList<String[]> maxBigcodeList = new ArrayList<>();// 高清大图下载地址： [路径,皮肤文件编码]

        try {
            CloseableHttpClient client = getHttpClient();
            HttpGet httpget = new HttpGet();
            // 防止HttpClient发送http请求时403 Forbidden和安全拦截
            String userAgent = "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.87 Safari/537.36";
            httpget.setHeader("User-Agent", userAgent);

            for (String[] line : codeList) {
                String country = StringUtils.isBlank(line[0]) ? "其他" : line[0];
                String name = StringUtils.isBlank(line[1]) ? "无名" : line[1];
                String code = line[2]; // X
                if (StringUtils.isBlank(code) || code.equalsIgnoreCase("XXX")) {
                    continue;
                }

                String skincode;// 皮肤完整编码：ZX0Y
                String skinNum; // 00-99

                String skindir;// 末级皮肤目录
                String outdir;// 皮肤输出绝对路径
                for (int Z = 1; Z <= 6; Z++) {// Z皮肤等级 1-6

                    int notExist = 0;
                    for (int Y = 1; Y <= 99; Y++) {// 0Y皮肤编号 01-99
                        skinNum = Y < 10 ? "0" + Y : "" + Y;
                        skincode = Z + code + skinNum;
                        System.out.println(skincode);

                        httpget.setURI(URI.create(baseUrl + skincode + ".png"));
                        HttpResponse response = client.execute(httpget);
                        HttpEntity entity = response.getEntity();

                        if (entity.getContentLength() <= 1000) { // 小于1KB时，默认没有图片
                            EntityUtils.consume(entity);// 释放资源
                            notExist++;
                            if (notExist >= 4 || Y >= 6) { // 顺序遍历编号时，如果超过4次不存在，或者遍历至6时还未存在，则终止遍历
                                break;
                            }
                            continue;
                        }

                        skindir = skindirMap.computeIfAbsent(country + "." + name, k -> country + "/" +code + "." + name);

                        outdir = dir + "/" + skindir; // 皮肤存储路径
                        File dirfile = new File(outdir);
                        if (!dirfile.exists()) {
                            dirfile.mkdirs();
                        }
                        maxBigcodeList.add(new String[] { outdir, skincode });// 加入高清图下载列表

                        InputStream is = entity.getContent();

                        File skinfile = new File(outdir + "/" + skincode + ".png");
                        if (skinfile.exists()) {
                            skinfile = new File(outdir + "/" + skincode + renameSuffix + ".png");
                        }

                        int cache = 10 * 1024;
                        FileOutputStream fileout = new FileOutputStream(skinfile);
                        byte[] buffer = new byte[cache];
                        int ch = 0;
                        while ((ch = is.read(buffer)) != -1) {
                            fileout.write(buffer, 0, ch);
                        }
                        is.close();
                        fileout.flush();
                        fileout.close();
                    }
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return maxBigcodeList;

    }


    /**
     * OL皮肤下载
     * @param baseUrl
     * @param dir
     * @param renameSuffix
     * @param csvfilePath
     * @return
     * @author liyas
     * @since 2023-2-19
     */
    private static ArrayList<String[]> download_ol_fromCsv(String baseUrl, String dir, String renameSuffix, String csvfilePath) throws IOException, CsvException {
        // 读取csv
        ArrayList<String[]> codeList = readCsvfile(csvfilePath);
        ArrayList<String[]> maxBigcodeList = new ArrayList<>();// 高清大图下载地址： [路径,皮肤文件编码]

        try {
            CloseableHttpClient client = getHttpClient();
            HttpGet httpget = new HttpGet();
            // 防止HttpClient发送http请求时403 Forbidden和安全拦截
            String userAgent = "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.87 Safari/537.36";
            httpget.setHeader("User-Agent", userAgent);

            for (String[] line : codeList) {
                String country = StringUtils.isBlank(line[0]) ? "其他" : line[0];
                String name = StringUtils.isBlank(line[1]) ? "无名" : line[1];
                String code = line[2]; // X
                if (StringUtils.isBlank(code) || code.equalsIgnoreCase("XXX")) {
                    continue;
                }

                String skincode;// 皮肤完整编码：X0Y
                String skinNum; // 00-99

                String skindir;// 末级皮肤目录
                String outdir;// 皮肤输出绝对路径

                int notExist = 0;
                for (int Y = 0; Y <= 99; Y++) {// 0Y皮肤编号 00-99
                    skinNum = Y < 10 ? "0" + Y : "" + Y;
                    skincode = code + skinNum;
                    System.out.println(skincode);

                    httpget.setURI(URI.create(baseUrl + skincode + ".png"));
                    HttpResponse response = client.execute(httpget);
                    HttpEntity entity = response.getEntity();

                    notExist = 0;
                    if (entity.getContentLength() <= 1000) { // 小于1KB时，默认没有图片
                        EntityUtils.consume(entity);// 释放资源
                        notExist++;
                        if (notExist >= 4 || Y >= 6) { // 顺序遍历编号时，如果超过4次不存在，或者遍历至6时还未存在，则终止遍历
                            break;
                        }
                        continue;
                    }

                    skindir = skindirMap.computeIfAbsent(country + "." + name, k -> country + "/" + code + "." + name);

                    outdir = dir + "/" + skindir; // 皮肤存储路径
                    File dirfile = new File(outdir);
                    if (!dirfile.exists()) {
                        dirfile.mkdirs();
                    }
                    maxBigcodeList.add(new String[] { outdir, skincode });// 加入高清图下载列表

                    InputStream is = entity.getContent();

                    File skinfile = new File(outdir + "/" + skincode + ".png");
                    if (skinfile.exists()) {
                        skinfile = new File(outdir + "/" + skincode + renameSuffix + ".png");
                    }

                    int cache = 10 * 1024;
                    FileOutputStream fileout = new FileOutputStream(skinfile);
                    byte[] buffer = new byte[cache];
                    int ch = 0;
                    while ((ch = is.read(buffer)) != -1) {
                        fileout.write(buffer, 0, ch);
                    }
                    is.close();
                    fileout.flush();
                    fileout.close();
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return maxBigcodeList;

    }


    /**
     * 从csv中读取完整编码下载
     * @param baseUrl
     * @param dir
     * @param renameSuffix
     * @param csvfilePath
     * @return
     * @author liyas
     * @since 2023-2-19
     */
    private static ArrayList<String[]> downloadBycode_fromCsv(String baseUrl, String dir, String renameSuffix, String csvfilePath) throws IOException, CsvException {
        // 读取csv
        ArrayList<String[]> codeList = readCsvfile(csvfilePath);
        ArrayList<String[]> maxBigcodeList = new ArrayList<>();// 高清大图下载地址： [路径,皮肤文件编码]

        try {
            CloseableHttpClient client = getHttpClient();
            HttpGet httpget = new HttpGet();
            // 防止HttpClient发送http请求时403 Forbidden和安全拦截
            String userAgent = "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.87 Safari/537.36";
            httpget.setHeader("User-Agent", userAgent);

            for (String[] line : codeList) {
                String country = StringUtils.isBlank(line[0]) ? "其他" : line[0];
                String name = StringUtils.isBlank(line[1]) ? "无名" : line[1];
                String code = line[2]; // 武将编号
                String skincode = line[3]; // 完整皮肤编号
                if (StringUtils.isBlank(code) || code.equalsIgnoreCase("XXX")) {
                    continue;
                }
                System.out.println(skincode);

                httpget.setURI(URI.create(baseUrl + skincode + ".png"));
                HttpResponse response = client.execute(httpget);
                HttpEntity entity = response.getEntity();

                if (entity.getContentLength() <= 1000) { // 小于1KB时，默认没有图片
                    EntityUtils.consume(entity);// 释放资源
                    continue;
                }

                String skindir = skindirMap.computeIfAbsent(country + "." + name, k -> country + "/" + code + "." + name);
                String outdir = dir + "/" + skindir; // 皮肤存储路径
                File dirfile = new File(outdir);
                if (!dirfile.exists()) {
                    dirfile.mkdirs();
                }
                maxBigcodeList.add(new String[] { outdir, skincode });// 加入高清图下载列表

                InputStream is = entity.getContent();

                File skinfile = new File(outdir + "/" + skincode + ".png");
                if (skinfile.exists()) {
                    skinfile = new File(outdir + "/" + skincode + renameSuffix + ".png");
                }

                int cache = 10 * 1024;
                FileOutputStream fileout = new FileOutputStream(skinfile);
                byte[] buffer = new byte[cache];
                int ch = 0;
                while ((ch = is.read(buffer)) != -1) {
                    fileout.write(buffer, 0, ch);
                }
                is.close();
                fileout.flush();
                fileout.close();
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return maxBigcodeList;
    }

    /**
     * 下载高清大图
     *
     * @param baseUrl      高清大图链接地址
     * @param renameSuffix 重命名后缀
     * @param codelist     下载列表[路径,皮肤文件编码]
     * @author liyas
     * @since 2023-2-19
     */
    private static void downloadMaxbig(String baseUrl, String renameSuffix, ArrayList<String[]> codelist) {
        try {
            CloseableHttpClient client = getHttpClient();
            HttpGet httpget = new HttpGet();
            // 防止HttpClient发送http请求时403 Forbidden和安全拦截
            String userAgent = "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.87 Safari/537.36";
            httpget.setHeader("User-Agent", userAgent);

            for (String[] data : codelist) {
                String outdir = data[0];// 皮肤存储路径
                String skincode = data[1];// 皮肤完整编码：ZX0Y

                System.out.println("maxBig:" + skincode);

                httpget.setURI(URI.create(baseUrl + skincode + ".png"));
                HttpResponse response = client.execute(httpget);
                HttpEntity entity = response.getEntity();

                if (entity.getContentLength() <= 1000) { // 小于1KB时，默认没有图片
                    EntityUtils.consume(entity);// 释放资源
                    continue;
                }

                InputStream is = entity.getContent();

                File skinfile = new File(outdir + "/" + skincode + ".max.png");
                if (skinfile.exists()) {
                    skinfile = new File(outdir + "/" + skincode + renameSuffix + ".max.png");
                }

                int cache = 10 * 1024;
                FileOutputStream fileout = new FileOutputStream(skinfile);
                byte[] buffer = new byte[cache];
                int ch = 0;
                while ((ch = is.read(buffer)) != -1) {
                    fileout.write(buffer, 0, ch);
                }
                is.close();
                fileout.flush();
                fileout.close();
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }



    private static void download_2023(String url, String dir, Integer begin, Integer end, String type) {
        try {
            File dirfile = new File(dir);
            if (!dirfile.exists()) {
                dirfile.mkdirs();
            }
            // SSLContext ctx = SSLContext.getInstance(SSLConnectionSocketFactory.TLS);
            SSLConnectionSocketFactory scsf = new SSLConnectionSocketFactory(SSLContexts.custom()
                    .loadTrustMaterial(null, new TrustSelfSignedStrategy()).setProtocol(SSLConnectionSocketFactory.TLS).build(),
                    NoopHostnameVerifier.INSTANCE);
            CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(scsf).build();

            for (int N = 4; N <= 6; N++) {
                for (int num = begin; num <= end; num++) {
                    String prefix = N + "" + num; // 图片代码前缀
                    for (int i = 1; i < 6; i++) { // 图片从01到09
                        String fileName = prefix + "0" + i + ".png"; // 图片代码
                        System.out.println(fileName);

                        HttpGet httpget = new HttpGet(url + fileName);
                        // 防止HttpClient发送http请求时403 Forbidden和安全拦截
                        String userAgent = "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.87 Safari/537.36";
                        httpget.setHeader("User-Agent", userAgent);

                        HttpResponse response = client.execute(httpget);
                        HttpEntity entity = response.getEntity();
                        // 内容类型
                        // System.out.println(entity.getContentType());
                        // 内容的编码格式
                        // System.out.println(entity.getContentEncoding());
                        // 内容的长度
                        // System.out.println(entity.getContentLength());
                        // 把内容转成字符串
                        // System.out.println(EntityUtils.toString(entity));
                        if (entity.getContentLength() <= 1000) { // 小于1KB时，默认没有图片
                            EntityUtils.consume(entity);// 释放资源
                            if ("big".equals(type)) {
                                break;
                            }
                            continue;
                        }

                        InputStream is = entity.getContent();

                        int cache = 10 * 1024;
                        FileOutputStream fileout = new FileOutputStream(dir + "/" + fileName);
                        byte[] buffer = new byte[cache];
                        int ch = 0;
                        while ((ch = is.read(buffer)) != -1) {
                            fileout.write(buffer, 0, ch);
                        }
                        is.close();
                        fileout.flush();
                        fileout.close();
                    }

                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static void download(String url, String dir, Integer begin, Integer end, String type) {
        try {
            File dirfile = new File(dir);
            if (!dirfile.exists()) {
                dirfile.mkdirs();
            }
            CloseableHttpClient client = getHttpClient();

            // 138645
            for (int pre = begin; pre <= end; pre++) {
                for (int i = 1; i < 10; i++) {
                    String fileName = pre + "0" + i + ".png";
                    System.out.println(fileName);

                    HttpGet httpget = new HttpGet(url + fileName);
                    // 防止HttpClient发送http请求时403 Forbidden和安全拦截
                    String userAgent = "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.87 Safari/537.36";
                    httpget.setHeader("User-Agent", userAgent);

                    HttpResponse response = client.execute(httpget);
                    HttpEntity entity = response.getEntity();
                    // 内容类型
                    // System.out.println(entity.getContentType());
                    // 内容的编码格式
                    // System.out.println(entity.getContentEncoding());
                    // 内容的长度
                    // System.out.println(entity.getContentLength());
                    // 把内容转成字符串
                    // System.out.println(EntityUtils.toString(entity));
                    if (entity.getContentLength() <= 1000) {
                        EntityUtils.consume(entity);// 释放资源
                        if ("big".equals(type)) {
                            break;
                        }
                        continue;
                    }

                    InputStream is = entity.getContent();

                    int cache = 10 * 1024;
                    FileOutputStream fileout = new FileOutputStream(dir + "/" + fileName);
                    byte[] buffer = new byte[cache];
                    int ch = 0;
                    while ((ch = is.read(buffer)) != -1) {
                        fileout.write(buffer, 0, ch);
                    }
                    is.close();
                    fileout.flush();
                    fileout.close();
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 读取csv文件
     *
     * @param filePath 文件名(带路径)
     * @return
     * @author liyas
     * @since 2023-2-19
     */
    private static ArrayList<String[]> readCsvfile(String filePath) throws IOException, CsvException {
        ArrayList<String[]> csvList = new ArrayList<String[]>();

        try (Reader reader = new InputStreamReader(new FileInputStream(filePath), Charset.forName("UTF-8"));
             CSVReader csvReader = new CSVReader(reader)) {
            csvList.addAll(csvReader.readAll());
        }

        return csvList;

    }

    private static CloseableHttpClient getHttpClient() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
        // SSLContext ctx = SSLContext.getInstance(SSLConnectionSocketFactory.TLS);
        SSLConnectionSocketFactory scsf = new SSLConnectionSocketFactory(SSLContexts.custom()
                .loadTrustMaterial(null, new TrustSelfSignedStrategy()).setProtocol(SSLConnectionSocketFactory.TLS).build(),
                NoopHostnameVerifier.INSTANCE);
        CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(scsf).build();
        return client;
    }


    /**
     * @param mapDirpath 需要的结构目录
     * @param desDirpath 文件输出目录
     * @param srcDirpath 源文件目录
     * @param codeFilepath 编码文件
     * @throws Exception
     * @author liyas
     * @since 2023-3-8
     */
    private static void reorganizeFiles(String mapDirpath, String desDirpath, String srcDirpath, String codeFilepath) throws Exception {
        // 初始化目标文件名映射
        initSkindirMap(mapDirpath);

        // 初始化源文件名映射
        iniSkinsrcMap(codeFilepath);

        File srcDir = new File(srcDirpath);
        String prefix = "";

        handleFile(srcDir, prefix, desDirpath);
    }

    /**
     * @param dirFile 文件目录
     * @param prefix 文件前缀名
     * @param desDirpath 输出目录
     * @throws IOException
     * @author liyas
     * @since 2023-3-8
     */
    private static void handleFile(File dirFile, String prefix, String desDirpath) throws IOException {
        for (File file : dirFile.listFiles()) {
            if ("char".equals(file.getParentFile().getName())) {
                prefix = "char.";
            }
            if (file.isDirectory()) {
                handleFile(file, prefix, desDirpath);
                continue;
            }
            // 从文件名提取编码
            String code;
            if ("char.".equals(prefix)) {
                code = file.getName().substring(0, file.getName().indexOf("_")); // 1_1.jpg
            } else {
                code = file.getName().substring(0, file.getName().indexOf("_") - 2); // 101_1.jpg
            }

            String countryname = skinsrcMap.getOrDefault(code, "未知." + code);
            // 蜀.刘备 -> 蜀/1.刘备
            String countrydir = skindirMap.computeIfAbsent(countryname, k -> countryname.replace(".", "/" + code + "."));

            // 目标文件
            File desfile = new File(desDirpath + "/" + countrydir + "/" + prefix + file.getName());
            if(!desfile.getParentFile().exists()) {
                desfile.getParentFile().mkdirs();
            }

            // 复制文件,保持文件名不变
            Files.copy(file.toPath(), desfile.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING);
        }
    }

}
